﻿using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
using SdmxMl.GenericMetadata;
using SdmxMl.Manager;
using SdmxMl.Common;
using SdmxMl.Structure;
using SdmxMl.SanteSuisse;
using SdmxMl.Helper;
using SdmxMl.Multiplexor;

namespace SilcQuest.Grid
{
    public class IntegrityHeader
    {
        private SmManager sm;
        private int year;
        private List<MetadataSetType> listQuest;
        private Dictionary<string, string> dicoVar;
        private Dictionary<string, string> dicoHeader;
        private List<string> listMissInHeader;
        private List<string> listMissInMetadata;
        private List<string> listDuplicatedInMetadata;
        private string headerPath;
        private List<string> artefactsQuest;

        private static string personHeaderPath = @"C:\Doc\Data SILC\HeaderP.txt";
        private static string householdHeaderPath = @"C:\Doc\Data SILC\HeaderH.txt";

        public IntegrityHeader(SmManager smMgr, int yearOfControl, bool isPerson)
        {

            sm = smMgr == null ? new SmManager() : smMgr;
            year = yearOfControl;
            headerPath = isPerson ? personHeaderPath : householdHeaderPath;

            listQuest = new List<MetadataSetType>();
            dicoVar = new Dictionary<string,string>();
            dicoHeader = new Dictionary<string,string>();
            listMissInHeader = new List<string>();
            listMissInMetadata = new List<string>();
            listDuplicatedInMetadata = new List<string>();

            // Prepare artefacts concerned
            artefactsQuest = new List<string>();
            if (isPerson)
            {
                artefactsQuest.AddRange(new string[] 
                { "PERSONS", "GMD_TECH_PERSONS", "CHILDREN", "GMD_TECH_CHILDREN", "PROXY", "GMD_TECH_PROXY" });
            }
            else
            {
                artefactsQuest.AddRange(new string[] { "HOUSEHOLD", "GMD_TECH_HOUSEHOLD", "GRID", "GMD_TECH_GRID" });
            }
            
        }

        private void LoadRequiredQuest()
        {
            try
            {
                // Todo determine last version for each
                string version = year.ToString() + ".0";
                SilcGroupInfo silcGroup = new SilcGroupInfo();
                foreach (string artQuest in artefactsQuest)
                {
                    listQuest.Add(sm.GetArtefact(SdmxArtefactType.MetadataSet,
                        new ArtefactRefBase(artQuest, silcGroup.AgencyId, version), true) as MetadataSetType);
                }
            }
            catch (Exception ex)
            {
                throw new ApplicationException("Unable to fetch required questionnaires" + Environment.NewLine + ex.Message);
            }

        }

        private void LoadDataHeader()
        {
            using (StreamReader sr = new StreamReader(headerPath, Encoding.Default))
            {
                string head = sr.ReadToEnd().TrimEnd(new char [] {'\r', '\n' });;
                string[]arr = head.Split(',');
                foreach (string s in arr)
                {
                    string colName = s.ToUpper();
                    if (dicoHeader.ContainsKey (colName) == true)
                        throw new ApplicationException("Unexpected header column already defined: " + colName);
                    dicoHeader.Add(colName, string.Empty);
                }
            }
        }

        public bool CheckHeader()
        {
            bool isOk = true;
            int deceny = year % 2000;

            LoadRequiredQuest();
            LoadDataHeader();

            // for each quest
            foreach (MetadataSetType metaset in listQuest)
            {
            // create var name for specified year, add in dico
                foreach (AttributeValueSetType atv in metaset.AttributeValueSetList)
                {
                    string varYear = atv.TargetValuesTypeList.GetComponentValue("VARNAME").SimpleValue.Replace("$$", deceny.ToString()).ToUpper();

                    if (dicoVar.ContainsKey(varYear) == true)
                    {
                       // listDuplicatedInMetadata.Add(varYear);
                        throw new ApplicationException("Unexpected Meta Quest variable already defined: " + varYear);
                    }
                    else
                    {
                        dicoVar.Add(varYear, string.Empty);
                    }

                   // loop if var is matrix case, add in dico

                    // check if var is in data header, add in miss if not
                    if (dicoHeader.ContainsKey(varYear) == false)
                        listMissInHeader.Add(varYear);
                }
            }



            // Revert pass check all header in dico
            foreach (string headCol in dicoHeader.Keys)
                if (dicoVar.ContainsKey(headCol) == false)
                    listMissInMetadata.Add(headCol);

            // Persist two lisat
            using (StreamWriter sw = new StreamWriter(@"c:\doc\MissInQuest.txt", false, Encoding.Default))
            {
                foreach (string s in listMissInMetadata)
                    sw.WriteLine(s);
            }

            using (StreamWriter sw = new StreamWriter(@"c:\doc\MissInDataHeadert.txt", false, Encoding.Default))
            {
                foreach (string s in listMissInHeader)
                    sw.WriteLine(s);
            }

            using (StreamWriter sw = new StreamWriter(@"c:\doc\DupliDataHeadert.txt", false, Encoding.Default))
            {
                foreach (string s in listDuplicatedInMetadata)
                    sw.WriteLine(s);
            }

            
            return isOk;

        }
    }
}
